﻿using Core.DataAccess.Model;
using Core.Framework;
using DotNetty.Framework;
using DotNetty.Framework.BaseTriggers;
using Grain.Interfaces;
using iTool.ClusterComponent;
using System;
using System.Threading.Tasks;

namespace iTool.Connector.CommandWorkers
{
    [Worker("iTool")]
    public class NotifyMessageWorker : WorkerController
    {

        private iToolClusterHostClient iCluster;

        public NotifyMessageWorker(iToolClusterHostClient cluster)
        {
            this.iCluster = cluster;
        }

        /// <summary>
        /// 获取消息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        [MethodRoute("Get Message")]
        public async Task<DoWorkResponse> GetMessage(HandleDoWorkingContext context)
        {
            string channel = context.ChannelHandlerContext.GetChannel();
            var channelService = this.iCluster.GetService<IChannelService>(channel);
            var model = context.Message.GetParameterModel<NotifyMessageParameter>();

            if (model.MinDateTime == null)
            {
                model.MinDateTime = DateTime.Now;
            }

            Pagination result;

            if (model.IsGroup)
            {
                if (model.MinHistoryDateTime != null)
                {
                    result = await channelService.GetMessageOfGroup(model.Pagination, model.ReciveChannel, (DateTime)model.MinDateTime, (DateTime)model.MinHistoryDateTime);
                }
                else
                {
                    result = await channelService.GetMessageOfGroup(model.Pagination, model.ReciveChannel, (DateTime)model.MinDateTime);
                }
            }
            else
            {
                if (model.MinHistoryDateTime != null)
                {
                    result = await channelService.GetMessage(model.Pagination, model.ReciveChannel, (DateTime)model.MinDateTime, (DateTime)model.MinHistoryDateTime);
                }
                else
                {
                    result = await channelService.GetMessage(model.Pagination, model.ReciveChannel, (DateTime)model.MinDateTime);
                }
            }
            return this.GetWorkResponse(context, result);
        }

        /// <summary>
        /// 获取会话信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        [MethodRoute("Get Sesstion")]
        public async Task<DoWorkResponse> Get(HandleDoWorkingContext context)
        {
            string channel = context.ChannelHandlerContext.GetChannel();

            if (string.IsNullOrWhiteSpace(channel))
            {
                return this.GetErrorResponseOfParameterValidationFailed(context, "channel is null");
            }

            var channelService = this.iCluster.GetService<IChannelService>(channel);

            DateTime? lastDateTime = null;
            if (!string.IsNullOrWhiteSpace(context.Message.Parameter))
            {
                DateTime.TryParse(context.Message.Parameter, out DateTime dateTime);
                lastDateTime = dateTime;
            }

            var result = await channelService.GetSesstion(lastDateTime);
            return this.GetWorkResponse(context, result);
        }

        /// <summary>
        /// 消息已读
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        [MethodRoute("Sesstion Reader")]
        public async Task<DoWorkResponse> ReaderMessage(HandleDoWorkingContext context)
        {
            string channel = context.ChannelHandlerContext.GetChannel();
            var channelService = this.iCluster.GetService<IChannelService>(channel);
            await channelService.ReaderChannel(context.Message.Parameter);
            return this.GetWorkResponse(context, 1);
        }


        /// <summary>
        /// 进入某会话
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        [MethodRoute("Sesstion IntoChannel")]
        public async Task<DoWorkResponse> IntoChannel(HandleDoWorkingContext context)
        {
            string channel = context.ChannelHandlerContext.GetChannel();
            var channelService = this.iCluster.GetService<IChannelService>(channel);
            var result = await channelService.IntoChannel(context.Message.Parameter);
            return this.GetWorkResponse(context, new
            {
                isReciveInSession = result.Key,
                parameters = result.Value
            });
        }

        /// <summary>
        /// 退出某会话
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        [MethodRoute("Sesstion OutChannel")]
        public async Task<DoWorkResponse> OutChannel(HandleDoWorkingContext context)
        {
            string channel = context.ChannelHandlerContext.GetChannel();
            var channelService = this.iCluster.GetService<IChannelService>(channel);
            await channelService.OutChannel(context.Message.Parameter);
            return this.GetWorkResponse(context, 1);
        }

        /// <summary>
        /// 删除指定会话
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        [MethodRoute("Sesstion RemoveSesstionByChannel")]
        public async Task<DoWorkResponse> RemoveSesstionByChannel(HandleDoWorkingContext context)
        {
            string channel = context.ChannelHandlerContext.GetChannel();
            var channelService = this.iCluster.GetService<IChannelService>(channel);
            await channelService.RemoveSesstionByChannel(context.Message.Parameter);
            return this.GetWorkResponse(context, 1);
        }

        /// <summary>
        /// 更新消息状态
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        [MethodRoute("Modify MessageStatus")]
        public async Task<DoWorkResponse> ModifyMessageStatus(HandleDoWorkingContext context)
        {
            string channel = context.ChannelHandlerContext.GetChannel();
            var channelService = this.iCluster.GetService<IChannelService>(channel);
            var model = context.Message.GetParameterModel<DBNotifyMessage>();
            await channelService.ModifyMessageStatus(model);
            return this.GetWorkResponse(context, 1);
        }

    }
}
